//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2002-2007
//
// The Garmin-specific type set.
//

# include "StdAfx.h"
# include "Resource.h"
# include "GarminTypes.h"
# include "GarminRound.h"
# include "Map.h"
# include "Types.h"
# include "TypesDraw.h"
# include "TypesPOIDraw.h"
//# include "fvector.h"
# include "Globals.h"

bool Garmin_IsCity (USHORT _ushType) {
	const USHORT ushType = _ushType & 0xFF00;
	return 0x0100 <= ushType && ushType <= 0x1100;
}

bool Garmin_IsCity (const rgn_t & _rgn) {
	return _rgn.IsPoint () && Garmin_IsCity (_rgn.ushType);
}

bool Garmin_HasAddress (USHORT _ushType) {
	const USHORT ushType = _ushType & 0xFF00;
	return (0x2900 <= ushType && ushType <= 0x3000) || ushType == 0x1200;
}

bool Garmin_HasAddress (const rgn_t & _rgn) {
	return _rgn.IsPoint () && Garmin_HasAddress (_rgn.ushType);
}

bool Garmin_HasCityAndZip (const rgn_t & _rgn) {
	if (Garmin_IsCity (_rgn))
		return true;
	if (Garmin_HasAddress (_rgn))
		return true;
	if (Garmin_IsRoad (_rgn))
		return true;
	return false;
}

bool Garmin_HasPhone (const rgn_t & _rgn) {
	return Garmin_HasAddress (_rgn);
}

bool Garmin_HasDescription (const rgn_t & _rgn) {
	return false;
}

bool Garmin_IsHwExit (USHORT _ushType) {
	const USHORT ushType = _ushType & 0xFF00;
	return 0x2000 <= ushType && ushType <= 0x2700;
}

bool Garmin_IsHwExit (const rgn_t & _rgn) {
	return _rgn.IsPoint () && Garmin_IsHwExit (_rgn.ushType);
}

bool Garmin_IsHeight (const rgn_t & _rgn) {
	if (_rgn.IsPoint ()) {
		const USHORT ushType = _rgn.ushType & 0xFF00;
		return 0x6200 == ushType || ushType == 0x6300;
	} else if (_rgn.IsPolyline ()) {
		return 0x20 <= _rgn.ushType && _rgn.ushType <= 0x25;
	} else
		return false;
}

bool Garmin_IsFeature (const rgn_t & _rgn) {
	if (_rgn.IsPoint ()) {
		const USHORT ushType = _rgn.ushType & 0xFF00;
		return 0x6400 <= ushType && ushType <= 0x6600;
	} else
		return false;
}

bool Garmin_IsBackground (USHORT _ushType) {
	return _ushType == 0x4b;
}

bool Garmin_IsBackground (const rgn_t & _rgn) {
	return Garmin_IsBackground (_rgn.ushType) && _rgn.Kind == rkPolygon;
}

bool Garmin_IsRoad (USHORT _ushType) {
	if (0x00 <= _ushType && _ushType <= 0x0C)
		return true;
	if (_ushType == 0x16 || _ushType == 0x1a || _ushType == 0x1b)
		return true;
	return false;
}

bool Garmin_IsRoad (const rgn_t & _rgn) {
	return _rgn.IsPolyline () && Garmin_IsRoad (_rgn.ushType);
}

bool Garmin_IsUnpavedRoad (const rgn_t & _rgn) {
	return _rgn.IsPolyline () && _rgn.ushType == 0x0a;
}

///////////////////////////////////////////////

struct POI_desc_t {
	BYTE btPointCode;
	BYTE btPOISubcodeMin;
	BYTE btPOISubcodeMax;
	BYTE btCategory;

	char * strTypeName;

		// The icon for point/POI. NOTE: can't be NULL; use g_hcurUnknown for default.
	HCURSOR *      phCursor;

	label_desc_t * pLabelDesc;
};

static POI_desc_t g_POIs [] = {
	{0x01, 0x00, 0,    catCities,        "Large city (over 10M)",          & g_hcurCityMega,   & g_BigCityLabel},
	{0x02, 0x00, 0,    catCities,        "Large city (5-10M)",             & g_hcurCityMega,   & g_BigCityLabel},
	{0x03, 0x00, 0,    catCities,        "Large city (2-5M)",              & g_hcurCityBig,    & g_BigCityLabel},
	{0x04, 0x00, 0,    catCities,        "Large city (1-2M)",              & g_hcurCityMedium, & g_CityLabel},
	{0x05, 0x00, 0,    catCities,        "Medium city (0.5-1M)",           & g_hcurCityMedium, & g_CityLabel},
	{0x06, 0x00, 0,    catCities,        "Medium city (200-500K)",         & g_hcurCityMedium, & g_CityLabel},
	{0x07, 0x00, 0,    catCities,        "Medium city (100-200K)",         & g_hcurCitySmall},
	{0x08, 0x00, 0,    catCities,        "Small city (50-100K)",           & g_hcurCitySmall},
	{0x09, 0x00, 0,    catCities,        "Small city (20-50K)",            & g_hcurCitySmall},
	{0x0a, 0x00, 0,    catCities,        "Small city/town (10-20K)",       & g_hcurSettlement},
	{0x0b, 0x00, 0,    catCities,        "Small city/town (5-10K)",        & g_hcurSettlement},
	{0x0c, 0x00, 0,    catCities,        "Settlement (2-5K)",              & g_hcurSettlement},
	{0x0d, 0x00, 0,    catCities,        "Settlement (1-2K)",              & g_hcurSettlement},
	{0x0e, 0x00, 0,    catCities,        "Settlement (500-1K)",            & g_hcurNamedpoint},
	{0x0f, 0x00, 0,    catCities,        "Settlement (200-500)",           & g_hcurNamedpoint},
	{0x10, 0x00, 0,    catCities,        "Settlement (100-200)",           & g_hcurNamedpoint},
	{0x11, 0x00, 0,    catCities,        "Settlement (less 100)",          & g_hcurNamedpoint},

	{0x12, 0x00, 0x3F, catMarine,        "Marina with facilities",         & g_hcurWharf},
	// appears in some MapDekode maps
	{0x13, 0x00, 0x3F, catMarine,        "Marine unknown",                 & g_hcurUnknown},

	{0x14, 0x00, 0x3F, catLabels,        "Major country name",             & g_hcurRegion, & g_BigRegionLabel},
	{0x15, 0x00, 0x3F, catLabels,        "Minor country name",             & g_hcurRegion, & g_BigRegionLabel},

	{0x1c, 0x00, 0,    catMarineDanger,  "Obstruction",                    & g_hcurObstruction},
	{0x1c, 0x01, 0,    catMarineDanger,  "Wreck",                          & g_hcurWreckVisible},
	{0x1c, 0x02, 0,    catMarineDanger,  "Submerged wreck, dangerous",     & g_hcurWreckDangerous},
	{0x1c, 0x03, 0,    catMarineDanger,  "Submerged wreck, non-dangerous", & g_hcurWreckNonDangerous},
	{0x1c, 0x04, 0,    catMarineDanger,  "Wreck, cleared by wire-drag",    & g_hcurWreckDrag},
	{0x1c, 0x05, 0,    catMarineDanger,  "Obstr., visible at high water",  & g_hcurObstructionAwash},
	{0x1c, 0x06, 0,    catMarineDanger,  "Obstruction, awash",             & g_hcurObstructionAwash},
	{0x1c, 0x07, 0,    catMarineDanger,  "Obstruction, submerged",         & g_hcurObstruction},
	{0x1c, 0x08, 0,    catMarineDanger,  "Obstr., cleared by wire-drag",   & g_hcurObstructionDrag},
	{0x1c, 0x09, 0,    catMarineDanger,  "Rock, awash",                    & g_hcurReefAwash},
	{0x1c, 0x0a, 0,    catMarineDanger,  "Rock, submerged at low water",   & g_hcurReef},
	{0x1c, 0x0b, 0,    catMarineDanger,  "Possible grounding risk",        & g_hcurGrounding},

	{0x1d, 0x00, 0x3f, catMarine,        "Tide prediction",                & g_hcurWater},
//	{0x1d, 0x01, 0,    catMarine,        "Tide prediction",                & g_hcurWater},
	// in Garmin MapSource BlueCharts
//	{0x1d, 0x02, 0,    catMarine,        "Tide prediction",                & g_hcurWater},

	{0x1e, 0x00, 0x3f, catLabels,        "State/province/region name",     & g_hcurRegion, & g_RegionLabel},
	{0x1f, 0x00, 0x3f, catLabels,        "County/parish name",             & g_hcurRegion, & g_RegionLabel},

	{0x20, 0x00, 0x3f, catAuto,          "HW Exit",                        & g_hcurExit},
	{0x21, 0x00, 0x3f, catAuto,          "HW Exit with facilities",        & g_hcurExit},
	{0x21, 0x0F, 0,    catAuto,          "HW Exit (service)",              & g_hcurExit},
	{0x22, 0x00, 0x3f, catAuto,          "HW Exit (restroom)",             & g_hcurRestroom},
	{0x23, 0x00, 0x3f, catAuto,          "HW Exit (convenience store)",    & g_hcurExit},
	{0x24, 0x00, 0x3f, catAuto,          "HW Exit (weight station)",       & g_hcurWeight},
	{0x25, 0x00, 0x3f, catAuto,          "HW Exit (toll booth)",           & g_hcurToll},
	{0x26, 0x00, 0x3f, catAuto,          "HW Exit (information)",          & g_hcurInformation},
	{0x27, 0x00, 0x3f, catAuto,          "HW Exit",                        & g_hcurExit},

	{0x28, 0x00, 0x3f, catLabels,        "Label",                          & g_hcurRegion, & g_RegionLabel},

	{0x29, 0x00, 0x3f, catServices,      "Uncategorized business",         & g_hcurLand},

	{0x2a, 0x00, 0,    catFood,          "Dining",                         & g_hcurDining},
	{0x2a, 0x01, 0,    catFood,          "Dining (American)",              & g_hcurDining},
	{0x2a, 0x02, 0,    catFood,          "Dining (Asian)",                 & g_hcurDining},
	{0x2a, 0x03, 0,    catFood,          "Dining (barbecue)",              & g_hcurDining},
	{0x2a, 0x04, 0,    catFood,          "Dining (Chinese)",               & g_hcurDining},
	{0x2a, 0x05, 0,    catFood,          "Dining (Deli/Bakery)",           & g_hcurDining},
	{0x2a, 0x06, 0,    catFood,          "Dining (international)",         & g_hcurDining},
	{0x2a, 0x07, 0,    catFood,          "Fast food",                      & g_hcurDining},
	{0x2a, 0x08, 0,    catFood,          "Dining (Italian)",               & g_hcurDining},
	{0x2a, 0x09, 0,    catFood,          "Dining (Mexican)",               & g_hcurDining},
	{0x2a, 0x0a, 0,    catFood,          "Dining (pizza)",                 & g_hcurDining},
	{0x2a, 0x0b, 0,    catFood,          "Dining (sea food)",              & g_hcurDining},
	{0x2a, 0x0c, 0,    catFood,          "Dining (steak/grill)",           & g_hcurDining},
	{0x2a, 0x0d, 0,    catFood,          "Dining (bagel/donut)",           & g_hcurDining},
	{0x2a, 0x0e, 0,    catFood,          "Dining (cafe/diner)",            & g_hcurDining},
	{0x2a, 0x0f, 0,    catFood,          "Dining (French)",                & g_hcurDining},
	{0x2a, 0x10, 0,    catFood,          "Dining (German)",                & g_hcurDining},
	{0x2a, 0x11, 0,    catFood,          "Dining (British Isles)",         & g_hcurDining},
	{0x2a, 0x12, 0,    catFood,          "Special food products",          & g_hcurDining},

	{0x2b, 0x00, 0,    catLodging,       "Lodging",                        & g_hcurHotel},
	{0x2b, 0x01, 0,    catLodging,       "Hotel/Motel",                    & g_hcurHotel},
	{0x2b, 0x02, 0,    catLodging,       "Bed&Breakfast inn",              & g_hcurHotel},
	{0x2b, 0x03, 0,    catLodging,       "Camping/RV-Park",                & g_hcurCamping},
	{0x2b, 0x04, 0,    catLodging,       "Resort",                         & g_hcurHotel},

	{0x2c, 0x00, 0,    catAttractions,   "Attraction",                     & g_hcurCulture},
	{0x2c, 0x01, 0,    catAttractions,   "Amusement/Theme park",           & g_hcurAmusementPark},
	{0x2c, 0x02, 0,    catAttractions,   "Museum/History",                 & g_hcurMuseum},
	{0x2c, 0x03, 0,    catAttractions,   "Library",                        & g_hcurLibrary},
	{0x2c, 0x04, 0,    catAttractions,   "Landmark",                       & g_hcurScenic},
	{0x2c, 0x05, 0,    catEducation,     "School",                         & g_hcurSchool},
	{0x2c, 0x06, 0,    catAttractions,   "Park/Garden",                    & g_hcurPark},
	{0x2c, 0x07, 0,    catAttractions,   "Zoo/Aquarium",                   & g_hcurZoo},
	{0x2c, 0x08, 0,    catAttractions,   "Arena/Track",                    & g_hcurSports},
	{0x2c, 0x09, 0,    catAttractions,   "Hall/Auditorium",                & g_hcurCulture},
	{0x2c, 0x0a, 0,    catAttractions,   "Winery",                         & g_hcurWinery},
	{0x2c, 0x0b, 0,    catReligion,      "Place of worship",               & g_hcurChurch},
//	{0x2c, 0x0c, 0,    catAttractions,   "Hot spring",                     & g_hcurCulture},

	{0x2d, 0x00, 0,    catEntertainment, "Entertainment",                  & g_hcurLeasure},
	{0x2d, 0x01, 0,    catEntertainment, "Live theatre",                   & g_hcurTheatre},
	{0x2d, 0x02, 0,    catEntertainment, "Bar/Nightclub",                  & g_hcurBar},
	{0x2d, 0x03, 0,    catEntertainment, "Cinema",                         & g_hcurCinema},
	{0x2d, 0x04, 0,    catEntertainment, "Casino",                         & g_hcurCasino},
	{0x2d, 0x05, 0,    catSports,        "Golf course",                    & g_hcurGolf},
	{0x2d, 0x06, 0,    catSports,        "Skiing center/resort",           & g_hcurSkiing},
	{0x2d, 0x07, 0,    catSports,        "Bowling center",                 & g_hcurBowling},
	{0x2d, 0x08, 0,    catSports,        "Ice skating",                    & g_hcurIceSkate},
	{0x2d, 0x09, 0,    catSports,        "Swimming pool",                  & g_hcurSwimming},
	{0x2d, 0x0a, 0,    catSports,        "Sports/Fitness Center",          & g_hcurSports},
	{0x2d, 0x0b, 0,    catSports,        "Public sports airport",          & g_hcurAirport},

	{0x2e, 0x00, 0,    catShopping,      "Shopping",                       & g_hcurShopping},
	{0x2e, 0x01, 0,    catShopping,      "Department store",               & g_hcurDepartmentStore},
	{0x2e, 0x02, 0,    catShopping,      "Grocery store",                  & g_hcurShopping},
	{0x2e, 0x03, 0,    catShopping,      "General merchandiser",           & g_hcurShopping},
	{0x2e, 0x04, 0,    catShopping,      "Shopping center",                & g_hcurShopping},
	{0x2e, 0x05, 0,    catShopping,      "Pharmacy",                       & g_hcurPharmacy},
	{0x2e, 0x06, 0,    catShopping,      "Convenience store",              & g_hcurShopping},
	{0x2e, 0x07, 0,    catShopping,      "Apparel",                        & g_hcurShopping},
	{0x2e, 0x08, 0,    catShopping,      "House and garden",               & g_hcurShopping},
	{0x2e, 0x09, 0,    catShopping,      "Home furnishing",                & g_hcurShopping},
	{0x2e, 0x0a, 0,    catShopping,      "Speciality retail",              & g_hcurShopping},
	{0x2e, 0x0b, 0,    catShopping,      "Computer/Software",              & g_hcurShopping},
//	{0x2e, 0x0c, 0,    catShopping,      "Others",                         & g_hcurShopping},

	{0x2f, 0x00, 0,    catServices,      "Generic services",               & g_hcurService},
	{0x2f, 0x01, 0,    catAuto,          "Auto fuel",                      & g_hcurPetrol},
	{0x2f, 0x02, 0,    catAuto,          "Auto rental",                    & g_hcurAutoRental},
	{0x2f, 0x03, 0,    catAuto,          "Auto repair",                    & g_hcurAutoRepair},
	{0x2f, 0x04, 0,    catTransport,     "Air transportation",             & g_hcurAirport},
	{0x2f, 0x05, 0,    catServices,      "Post office",                    & g_hcurPostOffice},
	{0x2f, 0x06, 0,    catServices,      "Bank/ATM",                       & g_hcurBank},
	{0x2f, 0x07, 0,    catAuto,          "Dealer/Auto parts",              & g_hcurCarDealer},
	{0x2f, 0x08, 0,    catTransport,     "Ground transportation",          & g_hcurBusStation},
	{0x2f, 0x09, 0,    catMarine,        "Marina/Boat repair",             & g_hcurWharf},
	{0x2f, 0x0a, 0,    catServices,      "Wrecker service",                & g_hcurAutoRepair},
	{0x2f, 0x0b, 0,    catAuto,          "Parking",                        & g_hcurParking},
	{0x2f, 0x0c, 0,    catServices,      "Rest area/Tourist info",         & g_hcurPicnic},
	{0x2f, 0x0d, 0,    catAuto,          "Automobile club",                & g_hcurAutoClub},
	{0x2f, 0x0e, 0,    catAuto,          "Car wash",                       & g_hcurAutoWash},
	{0x2f, 0x0f, 0,    catShopping,      "Garmin dealer",                  & g_hcurShopping},
	{0x2f, 0x10, 0,    catServices,      "Personal services",              & g_hcurService},
	{0x2f, 0x11, 0,    catServices,      "Business service",               & g_hcurService},
	{0x2f, 0x12, 0,    catServices,      "Communication service",          & g_hcurTelephone},
	{0x2f, 0x13, 0,    catServices,      "Repair service",                 & g_hcurService},
	{0x2f, 0x14, 0,    catServices,      "Social service",                 & g_hcurService},
	{0x2f, 0x15, 0,    catServices,      "Public utilities",               & g_hcurService},
	{0x2f, 0x16, 0,    catAuto,          "Truck stop",                     & g_hcurTruckStop},
	{0x2f, 0x17, 0,    catTransport,     "Transit service",                & g_hcurService},

	{0x30, 0x00, 0,    catEmrgGov,       "Emergency/Governmental",         & g_hcurPublic},
	{0x30, 0x01, 0,    catEmrgGov,       "Police station",                 & g_hcurPolice},
	{0x30, 0x02, 0,    catEmrgGov,       "Hospital",                       & g_hcurHospital},
	{0x30, 0x03, 0,    catEmrgGov,       "City hall",                      & g_hcurPublic},
	{0x30, 0x04, 0,    catEmrgGov,       "Court house",                    & g_hcurCourt},
	{0x30, 0x05, 0,    catEmrgGov,       "Community center",               & g_hcurPublic},
	{0x30, 0x06, 0,    catEmrgGov,       "Border crossing",                & g_hcurPublic},
	{0x30, 0x07, 0,    catEmrgGov,       "Government office",              & g_hcurPublic},
	{0x30, 0x08, 0,    catEmrgGov,       "Fire department",                & g_hcurFireDepartment},

	{0x40, 0x00, 0x3f, catSports,        "Golf",                           & g_hcurGolf},
	{0x41, 0x00, 0x3f, catRecreation,    "Fishing spot",                   & g_hcurFish},
	{0x42, 0x00, 0x3f, catAuto,          "Wreck",                          & g_hcurWreck},
	{0x43, 0x00, 0x3f, catMarine,        "Marina",                         & g_hcurWharf},
	{0x44, 0x00, 0x3f, catAuto,          "Gas station",                    & g_hcurPetrol},
	{0x45, 0x00, 0x3f, catFood,          "Restaurant",                     & g_hcurDining},
	{0x46, 0x00, 0x3f, catFood,          "Bar",                            & g_hcurBar},
	{0x47, 0x00, 0x3f, catMarine,        "Boat ramp",                      & g_hcurBoatRamp},
	{0x48, 0x00, 0x3f, catRecreation,    "Camping",                        & g_hcurCamping},
	{0x49, 0x00, 0x3f, catRecreation,    "Park",                           & g_hcurPark},
	{0x4a, 0x00, 0x3f, catRecreation,    "Picnic area",                    & g_hcurPicnic},
	{0x4b, 0x00, 0x3f, catEmrgGov,       "First aid station",              & g_hcurHospital},
	{0x4c, 0x00, 0x3f, catRecreation,    "Information",                    & g_hcurInformation},
	{0x4d, 0x00, 0x3f, catAuto,          "Parking",                        & g_hcurParking},
	{0x4e, 0x00, 0x3f, catRecreation,    "Restroom",                       & g_hcurRestroom},
	{0x4f, 0x00, 0x3f, catRecreation,    "Shower",                         & g_hcurShower},
	{0x50, 0x00, 0x3f, catRecreation,    "Drinking water",                 & g_hcurDrinkingWater},
	{0x51, 0x00, 0x3f, catServices,      "Telephone",                      & g_hcurTelephone},
	{0x52, 0x00, 0x3f, catRecreation,    "Scenic area",                    & g_hcurScenic},
	{0x53, 0x00, 0x3f, catSports,        "Skiing",                         & g_hcurSkiing},
	{0x54, 0x00, 0x3f, catRecreation,    "Swimming area",                  & g_hcurSwimming},
	{0x55, 0x00, 0x3f, catManMade,       "Dam",                            & g_hcurDam},
	{0x56, 0x00, 0x3f, catOthers,        "Controlled area",                & g_hcurControlled},
	{0x57, 0x00, 0x3f, catOthers,        "Danger area",                    & g_hcurDanger},
	{0x58, 0x00, 0x3f, catOthers,        "Restricted area",                & g_hcurRestricted},

	{0x59, 0x00, 0,    catAviation,      "Generic airport",                & g_hcurAirport},
	{0x59, 0x01, 0,    catAviation,      "Large airport",                  & g_hcurAirportLarge},
	{0x59, 0x02, 0,    catAviation,      "Medium airport",                 & g_hcurAirport},
	{0x59, 0x03, 0,    catAviation,      "Small airport",                  & g_hcurAirport},
	{0x59, 0x04, 0,    catAviation,      "Heliport",                       & g_hcurHeliport},
	{0x59, 0x05, 0x3f, catAviation,      "Airport",                        & g_hcurAirport},

	{0x5a, 0x00, 0x3f, catOthers,        "Mile marker",                    & g_hcurLocale},
	{0x5b, 0x00, 0x3f, catOthers,        "Bell",                           & g_hcurBell},
	{0x5c, 0x00, 0x3f, catOthers,        "Diving area",                    & g_hcurDiving},
	{0x5d, 0x00, 0x3f, catOthers,        "Daymark, green square",          & g_hcurBeaconSquare},
	{0x5e, 0x00, 0x3f, catOthers,        "Daymark, red triangle",          & g_hcurBeaconTriangle},
	{0x60, 0x00, 0x3f, catOthers,        "Horn",                           & g_hcurHorn},
	{0x61, 0x00, 0x3f, catOthers,        "House",                          & g_hcurBuilding},

	{0x62, 0x00, 0x3f, catElevation,     "Depth spot",                     & g_hcurTop,        & g_DepthSpotLabel},
	{0x63, 0x00, 0x3f, catElevation,     "Elevation spot",                 & g_hcurTop,        & g_ElevSpotLabel},

	{0x64, 0x00, 0,    catManMade,       "Man-made place",                 & g_hcurManMade,    & g_FeatureLabel},
	{0x64, 0x01, 0,    catManMade,       "Bridge",                         & g_hcurBridge,     & g_FeatureLabel},
	{0x64, 0x02, 0,    catManMade,       "Building",                       & g_hcurBuilding,   & g_FeatureLabel},
	{0x64, 0x03, 0,    catManMade,       "Cemetery",                       & g_hcurCemetery,   & g_FeatureLabel},
	{0x64, 0x04, 0,    catReligion,      "Church/mosque/etc",              & g_hcurChurch,     & g_FeatureLabel},
	{0x64, 0x05, 0,    catManMade,       "Civil bulding",                  & g_hcurPublic,     & g_FeatureLabel},
	{0x64, 0x06, 0,    catManMade,       "Crossing",                       & g_hcurPassing,    & g_FeatureLabel},
	{0x64, 0x07, 0,    catManMade,       "Dam",                            & g_hcurDam,        & g_FeatureLabel},
	{0x64, 0x08, 0,    catManMade,       "Hospital",                       & g_hcurHospital,   & g_FeatureLabel},
	{0x64, 0x09, 0,    catManMade,       "Levee",                          & g_hcurDam,        & g_FeatureLabel},
	{0x64, 0x0a, 0,    catManMade,       "Locale",                         & g_hcurLocale,     & g_FeatureLabel},
	{0x64, 0x0b, 0,    catManMade,       "Military",                       & g_hcurMilitary,   & g_FeatureLabel},
	{0x64, 0x0c, 0,    catManMade,       "Mine",                           & g_hcurMine,       & g_FeatureLabel},
	{0x64, 0x0d, 0,    catManMade,       "Oil field",                      & g_hcurOil,        & g_FeatureLabel},
	{0x64, 0x0e, 0,    catManMade,       "Park",                           & g_hcurPark,       & g_FeatureLabel},
	{0x64, 0x0f, 0,    catServices,      "Post office",                    & g_hcurPostOffice, & g_FeatureLabel},
	{0x64, 0x10, 0,    catEducation,     "School",                         & g_hcurSchool,     & g_FeatureLabel},
	{0x64, 0x11, 0,    catManMade,       "Tower",                          & g_hcurTower,      & g_FeatureLabel},
	{0x64, 0x12, 0,    catManMade,       "Trailhead",                      & g_hcurTrailHead,  & g_FeatureLabel},
	{0x64, 0x13, 0,    catManMade,       "Tunnel",                         & g_hcurTunnel,     & g_FeatureLabel},
	{0x64, 0x14, 0,    catManMade,       "Well",                           & g_hcurDrinkingWater, & g_FeatureLabel},
	{0x64, 0x15, 0,    catManMade,       "Historical (ghost) town",        & g_hcurGhostTown,  & g_FeatureLabel},
	{0x64, 0x16, 0,    catManMade,       "Subdivision of housing",         & g_hcurGhostTown,  & g_FeatureLabel},

	{0x65, 0x00, 0,    catWater,         "Water feature",                  & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x01, 0,    catWater,         "Arroyo",                         & g_hcurArroyo,     & g_FeatureLabel},
	{0x65, 0x02, 0,    catWater,         "Sand bar",                       & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x03, 0,    catWater,         "Bay",                            & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x04, 0,    catWater,         "Bend",                           & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x05, 0,    catWater,         "Canal",                          & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x06, 0,    catWater,         "Channel",                        & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x07, 0,    catWater,         "Cove",                           & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x08, 0,    catWater,         "Falls",                          & g_hcurFalls,      & g_FeatureLabel},
	{0x65, 0x09, 0,    catWater,         "Geyser",                         & g_hcurGeyser,     & g_FeatureLabel},
	{0x65, 0x0a, 0,    catWater,         "Glacier",                        & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x0b, 0,    catWater,         "Harbor",                         & g_hcurWater,      & g_FeatureLabel},
	{0x65, 0x0c, 0,    catWater,         "Island",                         & g_hcurIsland,     & g_FeatureLabel},
	{0x65, 0x0d, 0,    catWater,         "Lake",                           & g_hcurReservoir,  & g_FeatureLabel},
	{0x65, 0x0e, 0,    catWater,         "Rapids",                         & g_hcurFalls,      & g_FeatureLabel},
	{0x65, 0x0f, 0,    catWater,         "Reservoir",                      & g_hcurReservoir,  & g_FeatureLabel},
	{0x65, 0x10, 0,    catWater,         "Sea",                            & g_hcurReservoir,  & g_FeatureLabel},
	{0x65, 0x11, 0,    catWater,         "Spring",                         & g_hcurSpring,     & g_FeatureLabel},
	{0x65, 0x12, 0,    catWater,         "Stream",                         & g_hcurStream,     & g_FeatureLabel},
	{0x65, 0x13, 0,    catWater,         "Swamp",                          & g_hcurSwamp,      & g_FeatureLabel},

	{0x66, 0x00, 0,    catLand,          "Land feature",                   & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x01, 0,    catLand,          "Arch",                           & g_hcurArch,       & g_FeatureLabel},
	{0x66, 0x02, 0,    catLand,          "Area",                           & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x03, 0,    catLand,          "Basin",                          & g_hcurReservoir,  & g_FeatureLabel},
	{0x66, 0x04, 0,    catLand,          "Beach",                          & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x05, 0,    catLand,          "Bench",                          & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x06, 0,    catLand,          "Cape",                           & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x07, 0,    catLand,          "Cliff",                          & g_hcurCliff,      & g_FeatureLabel},
	{0x66, 0x08, 0,    catLand,          "Crater",                         & g_hcurCrater,     & g_FeatureLabel},
	{0x66, 0x09, 0,    catLand,          "Flat",                           & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x0a, 0,    catLand,          "Forest",                         & g_hcurTree,       & g_FeatureLabel},
	{0x66, 0x0b, 0,    catLand,          "Gap",                            & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x0c, 0,    catLand,          "Gut",                            & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x0d, 0,    catLand,          "Isthmus",                        & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x0e, 0,    catLand,          "Lava",                           & g_hcurLava,       & g_FeatureLabel},
	{0x66, 0x0f, 0,    catLand,          "Pillar",                         & g_hcurPillar,     & g_FeatureLabel},
	{0x66, 0x10, 0,    catLand,          "Plain",                          & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x11, 0,    catLand,          "Range",                          & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x12, 0,    catLand,          "Reserve",                        & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x13, 0,    catLand,          "Ridge",                          & g_hcurRock,       & g_FeatureLabel},
	{0x66, 0x14, 0,    catLand,          "Rock",                           & g_hcurRock,       & g_FeatureLabel},
	{0x66, 0x15, 0,    catLand,          "Slope",                          & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x16, 0,    catLand,          "Summit",                         & g_hcurHill,       & g_FeatureLabel},
	{0x66, 0x17, 0,    catLand,          "Valley",                         & g_hcurLand,       & g_FeatureLabel},
	{0x66, 0x18, 0,    catLand,          "Wooded area",                    & g_hcurTree,       & g_FeatureLabel},
};

static POI_desc_t g_MarinePOIs [] = {
	{0x16, 0x00, 0,    catMarineNavaids, "Navaid",                         & g_hcurNavaid},
	{0x16, 0x01, 0,    catMarineNavaids, "Fog horn",                       & g_hcurFogHorn},
	{0x16, 0x02, 0,    catMarineNavaids, "Radio beacon",                   & g_hcurRadioBeacon},
	{0x16, 0x03, 0,    catMarineNavaids, "Racon",                          & g_hcurRacon},
	{0x16, 0x04, 0,    catMarineNavaids, "Daybeacon, red triangle",        & g_hcurBeaconTriangle},
	{0x16, 0x05, 0,    catMarineNavaids, "Daybeacon, green square",        & g_hcurBeaconSquare},
	{0x16, 0x06, 0,    catMarineNavaids, "Daybeacon, white diamond",       & g_hcurBeaconDiamond},
	{0x16, 0x07, 0,    catMarineNavaids, "Unlit navaid, white",            & g_hcurUNavaidWhite},
	{0x16, 0x08, 0,    catMarineNavaids, "Unlit navaid, red",              & g_hcurUNavaidRed},
	{0x16, 0x09, 0,    catMarineNavaids, "Unlit navaid, green",            & g_hcurUNavaidGreen},
	{0x16, 0x0a, 0,    catMarineNavaids, "Unlit navaid, black",            & g_hcurUNavaidBlack},
	{0x16, 0x0b, 0,    catMarineNavaids, "Unlit navaid, yellow/amber",     & g_hcurUNavaidYellow},
	{0x16, 0x0c, 0,    catMarineNavaids, "Unlit navaid, orange",           & g_hcurUNavaidOrange},
	{0x16, 0x0d, 0,    catMarineNavaids, "Unlit navaid, multi colored",    & g_hcurUNavaidMulti},
	{0x16, 0x0e, 0,    catMarineNavaids, "Navaid, unknown",                & g_hcurNavaid},
	{0x16, 0x0f, 0,    catMarineNavaids, "Navaid, white",                  & g_hcurNavaidWhite},
	{0x16, 0x10, 0,    catMarineNavaids, "Navaid, red",                    & g_hcurNavaidRed},
	{0x16, 0x11, 0,    catMarineNavaids, "Navaid, green",                  & g_hcurNavaidGreen},
	{0x16, 0x12, 0,    catMarineNavaids, "Navaid, yellow/amber",           & g_hcurNavaidYellow},
	{0x16, 0x13, 0,    catMarineNavaids, "Navaid, orange",                 & g_hcurNavaidOrange},
	{0x16, 0x14, 0,    catMarineNavaids, "Navaid, violet",                 & g_hcurNavaidViolet},
	{0x16, 0x15, 0,    catMarineNavaids, "Navaid, blue",                   & g_hcurNavaidBlue},
	{0x16, 0x16, 0,    catMarineNavaids, "Navaid, multi colored",          & g_hcurNavaidMulti},
};

struct polyline_desc_t {
	BYTE btCode;
	BYTE btCategory;

	char * strTypeName;

		// The pens to draw polylines .
	HPEN *         phPen;
		// The pen for second pass. NOTE: NULL means not to draw 2nd pass.
	HPEN *         phPen2;

	label_desc_t * pLabelDesc;
};

static polyline_desc_t g_Polylines [] = {
	// appears in some MapDekode maps
	{0x00, catRoads,      "Road",                        & g_hpenThinRoad,     NULL,                 & g_RoadLabel},

	{0x01, catRoads,      "Major highway",               & g_hpenHighway1,     & g_hpenHighway2,     & g_RoadLabel},
	{0x02, catRoads,      "Principal highway",           & g_hpenPrincipalHw,  NULL,                 & g_RoadLabel},
	{0x03, catRoads,      "Other highway road",          & g_hpenOtherHw,      NULL,                 & g_RoadLabel},
	{0x04, catRoads,      "Arterial road",               & g_hpenArterialRoad, NULL,                 & g_RoadLabel},
	{0x05, catRoads,      "Collector road",              & g_hpenCollectorRoad,NULL,                 & g_RoadLabel},
	{0x06, catRoads,      "Residential street",          & g_hpenThinRoad,     NULL,                 & g_RoadLabel},
	{0x07, catRoads,      "Alleyway/private driveway",   & g_hpenAlleyway,     NULL,                 & g_RoadLabel},
	{0x08, catRoads,      "Highway ramp, low-speed",     & g_hpenThinRoad,     NULL,                 & g_RoadLabel},
	{0x09, catRoads,      "Highway ramp, high-speed",    & g_hpenThinRoad,     NULL,                 & g_RoadLabel},
	{0x0a, catRoads,      "Unpaved road",                & g_hpenUnpavedRoad,  NULL,                 & g_RoadLabel},
	{0x0b, catRoads,      "Major highway connector",     & g_hpenPrincipalHw,  NULL,                 & g_RoadLabel},
	{0x0c, catRoads,      "Roundabout",                  & g_hpenThinRoad,     NULL,                 & g_RoadLabel},

	{0x14, catRoads,      "Railroad",                    & g_hpenRailroad1,    & g_hpenRailroad2,    & g_DefLabel},
	{0x15, catWater,      "Shoreline of water body",     & g_hpenCoast,        NULL,                 & g_DefLabel},
	{0x16, catRoads,      "Walkway/trail",               & g_hpenTrail,        NULL,                 & g_RoadLabel},

	{0x18, catWater,      "Stream",                      & g_hpenWater,        NULL,                 & g_LineRiverLabel},

	{0x19, catBoundaries, "Time-zone",                   & g_hpenTimeZone,     NULL,                 & g_DefLabel},
	{0x1a, catRoads,      "Water or rail ferry",         & g_hpenFerry,        NULL,                 & g_DefLabel},
	{0x1b, catRoads,      "Water or rail ferry",         & g_hpenFerry,        NULL,                 & g_DefLabel},

	{0x1c, catBoundaries, "State/province boundary",     & g_hpenBoundaryReg1, & g_hpenBoundaryReg2, & g_BoundaryLabel},
	{0x1d, catBoundaries, "County/parish boundary",      & g_hpenBoundaryCnt1, & g_hpenBoundaryCnt2, & g_BoundaryLabel},
	{0x1e, catBoundaries, "International boundary",      & g_hpenBoundaryInt1, & g_hpenBoundaryInt2, & g_BoundaryLabel},

	{0x1f, catWater,      "River",                       & g_hpenWater,        NULL,                 & g_LineRiverLabel},

	{0x20, catElevation,  "Minor land contour (1/10)",   & g_hpenHeight1,      NULL,                 & g_ContourLabel},
	{0x21, catElevation,  "Interm. land contour (1/2)",  & g_hpenHeight2,      NULL,                 & g_ContourLabel},
	{0x22, catElevation,  "Major land contour (1/1)",    & g_hpenHeight3,      NULL,                 & g_ContourLabel},

	{0x23, catElevation,  "Minor depth contour (1/10)",  & g_hpenDepth1,       NULL,                 & g_DepthLabel},
	{0x24, catElevation,  "Interm. depth contour (1/2)", & g_hpenDepth2,       NULL,                 & g_DepthLabel},
	{0x25, catElevation,  "Major depth contour (1/1)",   & g_hpenDepth3,       NULL,                 & g_DepthLabel},

	{0x26, catWater,      "Intermittent stream/ditch",   & g_hpenDryWater,     NULL,                 & g_LineRiverLabel},

	{0x27, catManMade,    "Airport runway centerline",   & g_hpenHighway1,     & g_hpenHighway2,     & g_RoadLabel},

	{0x28, catManMade,    "Oil or water pipeline",       & g_hpenPipeLine,     NULL,                 & g_DefLabel},
	{0x29, catManMade,    "Power line",                  & g_hpenPowerLine,    NULL,                 & g_DefLabel},

	{0x2a, catWater,      "Marine boundary (no line)",   & g_hpenUnknown,      NULL,                 & g_DefLabel},
	{0x2b, catWater,      "Marine hazard (no line)",     & g_hpenUnknown,      NULL,                 & g_DefLabel},
};

struct polygon_desc_t {
	BYTE btCode;
	BYTE btCategory;

	char * strTypeName;

		// The brush to fill polygons.
	HBRUSH *       phBrush;
		// The pen to draw border.
	HPEN *         phPen;

	label_desc_t * pLabelDesc;
};

static polygon_desc_t g_Polygons [] = {
	// appears in some MPC maps
//	{0x00, catOthers,  "???",                       & g_hbrUnknown,       & g_hpenUnknown,   },

	{0x01, catCities,   "Large urban area (>200K)",  & g_hbrLargeUrbanHousing, & g_hpenNull,  },
	{0x02, catCities,   "Small urban area (<200K)",  & g_hbrSmallUrbanHousing, & g_hpenNull,  },
	{0x03, catCities,   "Rural housing area",        & g_hbrRuralHousing,  & g_hpenNull,      },

	{0x04, catManMade,  "Military base",             & g_hbrIndustrial,    & g_hpenNull,      },
	{0x05, catManMade,  "Parking lot",               & g_hbrParkingLot,    & g_hpenNull,      },
	{0x06, catBuilding, "Parking garage",            & g_hbrManMade,       & g_hpenNull,      },
	{0x07, catManMade,  "Airport",                   & g_hbrUtilities,     & g_hpenNull,      },
	{0x08, catManMade,  "Shopping center",           & g_hbrUtilities,     & g_hpenNull,      },
	{0x09, catManMade,  "Marina",                    & g_hbrUtilities,     & g_hpenNull,      },
	{0x0a, catManMade,  "University/College",        & g_hbrUtilities,     & g_hpenNull,      },
	{0x0b, catManMade,  "Hospital",                  & g_hbrUtilities,     & g_hpenNull,      },
	{0x0c, catManMade,  "Industrial complex",        & g_hbrIndustrial,    & g_hpenNull,      },
	{0x0d, catManMade,  "Reservation",               & g_hbrReservation,   & g_hpenNull,      },
	{0x0e, catManMade,  "Airport runway",            & g_hbrSquare,        & g_hpenBlackThin, },
	{0x13, catBuilding, "Building/Man-made area",    & g_hbrManMade,       & g_hpenNull,      },

	{0x14, catLand,    "National park",             & g_hbrForest,        & g_hpenNull,      },
	{0x15, catLand,    "National park",             & g_hbrForest,        & g_hpenNull,      },
	{0x16, catLand,    "National park",             & g_hbrForest,        & g_hpenNull,      },
	{0x17, catManMade, "City park",                 & g_hbrCityPark,      & g_hpenNull,      },

	{0x18, catSports,  "Golf course",               & g_hbrGolf,          & g_hpenNull,      },
	{0x19, catSports,  "Sports complex",            & g_hbrUtilities,     & g_hpenNull, },
	{0x1a, catManMade, "Cemetery",                  & g_hbrCemetery,      & g_hpenBlackThin, },

	{0x1e, catLand,    "State park",                & g_hbrForest,        & g_hpenNull,      },
	{0x1f, catLand,    "State park",                & g_hbrForest,        & g_hpenNull,      },
	{0x20, catLand,    "State park",                & g_hbrForest,        & g_hpenNull,      },

	{0x28, catWater,   "Sea/Ocean",                 & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x29, catWater,   "Blue-Unknown",              & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},

	{0x32, catWater,   "Sea",                       & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},

	{0x3b, catWater,   "Blue-Unknown",              & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x3c, catWater,   "Large lake (250-600 km2)",  & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x3d, catWater,   "Large lake (77-250 km2)",   & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x3e, catWater,   "Medium lake (25-77 km2)",   & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x3f, catWater,   "Medium lake (11-25 km2)",   & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x40, catWater,   "Small lake (0.25-11 km2)",  & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x41, catWater,   "Small lake (<0.25 km2)",    & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x42, catWater,   "Major lake (>3.3 tkm2)",    & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x43, catWater,   "Major lake (1.1-3.3 tkm2)", & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x44, catWater,   "Large lake (0.6-1.1 tkm2)", & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},

	{0x45, catWater,   "Blue-Unknown",              & g_hbrWater,         & g_hpenCoast,     & g_LakeLabel},
	{0x46, catWater,   "Major river (>1 km)",       & g_hbrWater,         & g_hpenCoast,     & g_RiverLabel},
	{0x47, catWater,   "Large river (200 m-1 km)",  & g_hbrWater,         & g_hpenCoast,     & g_RiverLabel},
	{0x48, catWater,   "Medium river (40-200 m)",   & g_hbrWater,         & g_hpenCoast,     & g_RiverLabel},
	{0x49, catWater,   "Small river (<40 m)",       & g_hbrWater,         & g_hpenCoast,     & g_RiverLabel},

	{0x4a, catOthers,  "Map selection area",        & g_hbrNull,          & g_hpenNull},
	{0x4b, catOthers,  "Map coverage area",         & g_hbrNull,          & g_hpenNull},

	{0x4c, catWater,   "Intermittent water",        & g_hbrDryWater,      & g_hpenDryWater,  & g_LakeLabel},

	{0x4d, catLand,    "Glacier",                   & g_hbrGlacier,       & g_hpenNull,      },
	{0x4e, catManMade, "Orchard/plantation",        & g_hbrOrchard,       & g_hpenNull,      },
	{0x4f, catLand,    "Scrub",                     & g_hbrScrub,         & g_hpenNull,      },
	{0x50, catLand,    "Forest",                    & g_hbrForest,        & g_hpenNull,      },
	{0x51, catWater,   "Wetland/swamp",             & g_hbrSwamp,         & g_hpenNull,      & g_LakeLabel},
	{0x52, catLand,    "Tundra",                    & g_hbrTundra,        & g_hpenNull,      },
	{0x53, catWater,   "Sand/tidal/mud flat",       & g_hbrSandFlat,      & g_hpenNull,      },
};

void InitGarminTypes (std::vector<type_desc_t> & _types) {
	//
	//
	//
	_types.push_back (g_tdUnknown);

	// Prepare POIs.
	size_t cPOI;
	for (cPOI = 0; cPOI < sizeof (g_POIs)/sizeof (g_POIs [0]); ++ cPOI) {
		const POI_desc_t & d = g_POIs [cPOI];

		_types.push_back (type_desc_t ());
		type_desc_t & td = _types.back ();

		td.ushType        = (USHORT (d.btPointCode) << 8) + d.btPOISubcodeMin;
		td.Kind           = rkPoint;
		td.ulType2        = td.ulType + (d.btPOISubcodeMax == 0 ? 0 : d.btPOISubcodeMax - d.btPOISubcodeMin);
		td.Category       = static_cast<type_category_t> (d.btCategory);

		td.strTypeName    = d.strTypeName;
		td.phCursor       = d.phCursor;
		td.phBrush        = NULL;
		td.phPen          = NULL;
		td.phPen2         = NULL;

		const label_desc_t * const pLD = d.pLabelDesc ? d.pLabelDesc : & g_DefLabel;
		td.phFont         = pLD->phFont;
		td.colText        = pLD->colText;
		td.pfPrepareLabel = pLD->pfPrepareLabel;
		td.pfDrawLabel    = pLD->pfDrawLabel;
	}

	// Prepare marine POIs.
	for (cPOI = 0; cPOI < sizeof (g_MarinePOIs)/sizeof (g_MarinePOIs [0]); ++ cPOI) {
		const POI_desc_t & d = g_MarinePOIs [cPOI];

		for (BYTE btPointCode = 0x16; btPointCode <= 0x1b; ++ btPointCode) {
			_types.push_back (type_desc_t ());
			type_desc_t & td = _types.back ();

			td.ushType        = (USHORT (btPointCode) << 8) + d.btPOISubcodeMin;
			td.Kind           = rkPoint;
			td.ulType2        = td.ulType;
			td.Category       = static_cast<type_category_t> (d.btCategory);

			td.strTypeName    = d.strTypeName;
			td.phCursor       = d.phCursor;
			td.phBrush        = NULL;
			td.phPen          = NULL;
			td.phPen2         = NULL;

			const label_desc_t * const pLD = d.pLabelDesc ? d.pLabelDesc : & g_DefLabel;
			td.phFont         = pLD->phFont;
			td.colText        = pLD->colText;
			td.pfPrepareLabel = pLD->pfPrepareLabel;
			td.pfDrawLabel    = pLD->pfDrawLabel;
		}
	}

	// Prepare polylines.
	for (size_t cPolyline = 0; cPolyline < sizeof (g_Polylines)/sizeof (g_Polylines [0]); ++ cPolyline) {
		const polyline_desc_t & d = g_Polylines [cPolyline];

		_types.push_back (type_desc_t ());
		type_desc_t & td = _types.back ();

		td.ushType        = d.btCode;
		td.Kind           = rkPolyline;
		td.ulType2        = td.ulType;
		td.Category       = static_cast<type_category_t> (d.btCategory);

		td.strTypeName    = d.strTypeName;
		td.phCursor       = NULL;
		td.phBrush        = NULL;
		td.phPen          = d.phPen;
		td.phPen2         = d.phPen2;

		const label_desc_t * const pLD = d.pLabelDesc ? d.pLabelDesc : & g_DefLabel;
		td.phFont         = pLD->phFont;
		td.colText        = pLD->colText;
		td.pfPrepareLabel = pLD->pfPrepareLabel;
		td.pfDrawLabel    = pLD->pfDrawLabel;
	}

	// Prepare polygons.
	for (size_t cPolygon = 0; cPolygon < sizeof (g_Polygons)/sizeof (g_Polygons [0]); ++ cPolygon) {
		const polygon_desc_t & d = g_Polygons [cPolygon];

		_types.push_back (type_desc_t ());
		type_desc_t & td = _types.back ();

		td.ushType        = d.btCode;
		td.Kind           = rkPolygon;
		td.ulType2        = td.ulType;
		td.Category       = static_cast<type_category_t> (d.btCategory);

		td.strTypeName    = d.strTypeName;
		td.phCursor       = NULL;
		td.phBrush        = d.phBrush;
		td.phPen          = d.phPen;
		td.phPen2         = NULL;

		const label_desc_t * const pLD = d.pLabelDesc ? d.pLabelDesc : & g_CenteredLabel;
		td.phFont         = pLD->phFont;
		td.colText        = pLD->colText;
		td.pfPrepareLabel = pLD->pfPrepareLabel;
		td.pfDrawLabel    = pLD->pfDrawLabel;
	}

	// Make sure all types are sorted by code (as required by GetTypeDesc()).
	std::sort (_types.begin (), _types.end ());

	// Check type ranges for consistency.
	size_t cType;
	for (cType = 0; cType < _types.size () - 1; ++ cType) {
		type_desc_t & td0 = _types [cType];
		type_desc_t & td1 = _types [cType + 1];

		assert (td0.ulType <= td0.ulType2);
		assert (td0.ulType < td1.ulType);

		if (td0.ulType2 > td1.ulType2) {
			_types.insert (_types.begin () + cType + 2, type_desc_t ());
			type_desc_t & td2 = _types [cType + 2];
			td2 = td0;
			td2.ulType = td1.ulType2 + 1;
			td2.ulType2 = td0.ulType2;

			td0.ulType2 = td1.ulType - 1;
		}
	}
}

static std::vector<type_desc_t> g_types_impl;

static
void _InitGarminTypes () {
	//
	// Prepare Garmin-specific POI icons.
	//

	InitGarminTypes (g_types_impl);

	// NOTE: here is assumed that STL stores vector as plain array.
	g_tsGarmin.pTypes           = & g_types_impl [0];
	g_tsGarmin.cTypes           = g_types_impl.size ();

	g_tsGarmin.strID            = "Garmin";
	g_tsGarmin.strDisplayName   = "Garmin";

	g_tsGarmin.pfGetLatGrid     = GarminLatGrid;
	g_tsGarmin.pfRoundPoint     = GarminRoundPoint;
	g_tsGarmin.pfRoundPoints    = GarminRoundPoints;
	g_tsGarmin.pfRoundRect      = GarminRoundRect;

	g_tsGarmin.pfIsCity         = Garmin_IsCity;
	g_tsGarmin.pfIsHeight       = Garmin_IsHeight;
	g_tsGarmin.pfIsFeature      = Garmin_IsFeature;
	g_tsGarmin.pfIsRoad         = Garmin_IsRoad;
	g_tsGarmin.pfIsUnpavedRoad  = Garmin_IsUnpavedRoad;
	g_tsGarmin.pfIsHwExit       = Garmin_IsHwExit;
	g_tsGarmin.pfIsBackground   = Garmin_IsBackground;
	g_tsGarmin.pfHasAddress     = Garmin_HasAddress;
	g_tsGarmin.pfHasCityAndZip  = Garmin_HasCityAndZip;
	g_tsGarmin.pfHasPhone       = Garmin_HasPhone;
	g_tsGarmin.pfHasContact     = RgnPredicateFalse;
	g_tsGarmin.pfHasDescription = Garmin_HasDescription;

	g_tsGarmin.dwFeatures       = CTypeSet::tsfHasCopyright | CTypeSet::tsfHasElevationUnits | CTypeSet::tsfHasRoadAddress;

	g_tsGarmin.cMaxBits         = 24;
}

static
void _DestroyGarminTypes () {}

CTypeSet g_tsGarmin (_InitGarminTypes, _DestroyGarminTypes);